package user_profile

import (
	"context"

	commonTools "algo-sdk-go/common/tools"
	"algo-sdk-go/project/matchmaking/common/biz_tools"
	"algo-sdk-go/project/matchmaking/common/constant"
	"algo-sdk-go/project/matchmaking/domain/models/entity"
	"algo-sdk-go/project/matchmaking/domain/port/repo/ops"
	"algo-sdk-go/project/matchmaking/matchMaking-api/internal/logic/mate_preference"
	"algo-sdk-go/project/matchmaking/matchMaking-api/internal/svc"
	"algo-sdk-go/project/matchmaking/matchMaking-api/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

type QueryUserprofileLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewQueryUserprofileLogic(ctx context.Context, svcCtx *svc.ServiceContext) *QueryUserprofileLogic {
	return &QueryUserprofileLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *QueryUserprofileLogic) QueryUserprofile(req *types.QueryUserprofileRequest) (resp *types.QueryUserprofileResponse, err error) {
	userProfile, totalNum, err := l.svcCtx.UserProfileService.GetUserProfile(l.ctx, BuildOpsCondition(req))
	if err != nil {
		return nil, err
	}

	resp = &types.QueryUserprofileResponse{
		Data: types.QueryUserprofileData{
			UserprofileList: commonTools.Cast(userProfile, CastUserProfile),
			TotalNum:        totalNum,
		},
	}
	return
}

func CastUserProfile(userProfile entity.UserProfile) types.UserProfile {
	return types.UserProfile{
		UserNum: userProfile.UserNum,
		Name:    userProfile.Name,
		Gender:  userProfile.Gender.Value(),
		Height:  userProfile.Height,
		Weight:  userProfile.Weight,
		//BMIDesc:       userProfile.BMIDesc,
		BirthDate:     userProfile.BirthDate,
		Age:           userProfile.Age,
		ChineseZodiac: userProfile.ChineseZodiac,
		MaritalStatus: userProfile.MaritalStatus.Value(),
		Assets: types.Assets{
			AnnualIncome: userProfile.Assets.AnnualIncome,
			Car:          userProfile.Assets.Car.Value(),
			House:        userProfile.Assets.House.Value(),
		},
		Education:        userProfile.Education.Value(),
		Occupation:       userProfile.Occupation.Value(),
		IsPartyMember:    userProfile.IsPartyMember,
		Hometown:         userProfile.Hometown,
		CurrentResidence: userProfile.CurrentResidence,
		FamilyMembers: types.FamilyMembers{
			FamilyType: userProfile.FamilyInfo.FamilyType.Value(),
			FatherDetail: types.RelationDetail{
				Age:  userProfile.FamilyInfo.FatherDetail.Age,
				Desc: userProfile.FamilyInfo.FatherDetail.Desc,
			},
			MotherDetail: types.RelationDetail{
				Age:  userProfile.FamilyInfo.MotherDetail.Age,
				Desc: userProfile.FamilyInfo.MotherDetail.Desc,
			},
			OtherDetail: commonTools.Cast(userProfile.FamilyInfo.OtherDetail, func(detail constant.RelationDetail) types.RelationDetail {
				return types.RelationDetail{
					Age:  detail.Age,
					Desc: detail.Desc,
				}
			}),
		},
		CreateUser: userProfile.CreateUser,
		ModifyUser: userProfile.ModifyUser,
		Verified:   userProfile.Verified,
	}
}

func calAge(ageRange types.AgeRange) (int, int) {
	if ageRange.MinAge != 0 || ageRange.MaxAge != 0 {
		return ageRange.MinAge, ageRange.MaxAge
	}

	maxAge, _, err := biz_tools.CalculateAgeAndZodiac(ageRange.MaxBrithday)
	if err != nil {
		return 0, 0
	}

	minAge, _, err := biz_tools.CalculateAgeAndZodiac(ageRange.MinBrithday)
	if err != nil {
		return 0, 0
	}
	return minAge, maxAge
}

func BuildOpsCondition(req *types.QueryUserprofileRequest) ops.Condition {
	minAge, maxAge := calAge(req.AgeRange)

	opsCondition := ops.Condition{
		UserNumList: req.UserNumList,
		Gender:      req.Gender,
		AgeRange: ops.AgeRange{
			MinAge: minAge,
			MaxAge: maxAge,
		},
		HeightRange: ops.HeightRange{
			MinHeight: req.HeightRange.MinHeight,
			MaxHeight: req.HeightRange.MaxHeight,
		},
		WeightRange: ops.WeightRange{
			MinWeight: req.WeightRange.MinWeight,
			MaxWeight: req.WeightRange.MaxWeight,
		},
		MaritalStatus: req.MaritalStatus,
		EducationRange: ops.EducationRange{
			MinEducation: constant.Education(req.EducationRange.MinEducation),
			MaxEducation: constant.Education(req.EducationRange.MaxEducation),
		},
		IncomeRange: ops.IncomeRange{
			MinIncome: req.IncomeRange.MinIncome,
			MaxIncome: req.IncomeRange.MaxIncome,
		},
		Occupation:                 req.Occupation,
		HometownPreference:         commonTools.Cast(req.HometownPreference, mate_preference.AddressCast),
		CurrentResidencePreference: commonTools.Cast(req.CurrentResidencePreference, mate_preference.AddressCast),
		ParentsHasPension:          req.ParentsHasPension,
		PageNum:                    commonTools.TernaryExpression(req.PageNum <= 0, 1, req.PageNum),
		PageSize:                   commonTools.TernaryExpression(req.PageSize <= 0, 20, req.PageSize),
		IgnorePage:                 false,
		SortBy:                     nil,
		WithStatus:                 false,
		WithDelete:                 false,
	}

	return opsCondition
}
